home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / system / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / Framework / Interface.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-26  |  20.8 KB  |  788 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // $Id: Interface.cxx,v 1.4 1995/01/15 22:45:49 bmott Exp $
  3. ///////////////////////////////////////////////////////////////////////////////
  4. // Interface.cxx
  5. //
  6. // This is the user interface command class.  It handles all of the
  7. // command's issue by the user interface.
  8. //
  9. //
  10. // BSVC "A Microprocessor Simulation Framework"
  11. // Copyright (c) 1993
  12. // By: Bradford W. Mott
  13. // October 21,1993
  14. //
  15. ///////////////////////////////////////////////////////////////////////////////
  16. // $Log: Interface.cxx,v $
  17. // Revision 1.4  1995/01/15  22:45:49  bmott
  18. // Had to cast the signal handler function
  19. //
  20. // Revision 1.3  1995/01/13  00:29:21  bmott
  21. // Changed all of the variable size arrays to be a fixed size to
  22. // conform to ansi C++ standards
  23. //
  24. // Revision 1.2  1995/01/01  03:46:51  bmott
  25. // Changed the ListMemory command
  26. //
  27. // Revision 1.1  1994/08/03  22:54:11  bmott
  28. // Initial revision
  29. //
  30. //
  31. ///////////////////////////////////////////////////////////////////////////////
  32.  
  33. #include "Interface.hxx"
  34. #include "Tools.hxx"
  35.  
  36. #include <unistd.h>
  37. #include <signal.h>
  38. #include <String.h>
  39. #include <iostream.h>
  40. #include <stdio.h>
  41. #include <string.h>
  42.  
  43. char *Interface::Get()
  44. {
  45.   char *command;
  46.  
  47.   command=new char[4096];
  48.   gets(command);
  49.  
  50.   return(command);
  51. }
  52.  
  53. void Interface::Put(const char *s)
  54. {
  55.   String tmp(s);
  56.  
  57.   tmp+="\n";
  58.   write(1,(char*)tmp,tmp.length());
  59. }
  60.  
  61. ///////////////////////////////////////////////////////////////////////////////
  62. // Simulator's main loop, Gets a command from the UI, parses and executes it.
  63. ///////////////////////////////////////////////////////////////////////////////
  64. void Interface::CommandLoop()
  65. {
  66.   char *command;
  67.  
  68.   Put("BSVC Simulator");
  69.  
  70.   while(1)
  71.   {
  72.     Put("Ready!");          // Prompt the user interface
  73.     command=Get();          // Get the next command from the UI
  74.  
  75.     if(ExecuteCommand(command))
  76.     {
  77.       delete[] command;
  78.       break;
  79.     }
  80.     else
  81.     {
  82.       delete[] command;
  83.     }
  84.   }
  85. }
  86.  
  87. ///////////////////////////////////////////////////////////////////////////////
  88. // Parse and execute the given command
  89. ///////////////////////////////////////////////////////////////////////////////
  90. int Interface::ExecuteCommand(const char *command)
  91. {
  92.   if(strcmp(command,"Exit")==0)
  93.     return(1);
  94.  
  95.   for(int t=0;t<number_of_commands;++t)
  96.   {
  97.     unsigned int length = strlen(command_table[t].name);
  98.     if(strncmp(command_table[t].name, command, length ) == 0)
  99.     {
  100.       (this->*command_table[t].mfp)((char*)&command[length]);
  101.       return(0);
  102.     }
  103.   }
  104.   Put("ERROR: Unknown command!");  
  105.   return(0);
  106. }
  107.  
  108. ///////////////////////////////////////////////////////////////////////////////
  109. // The user interface command table
  110. ///////////////////////////////////////////////////////////////////////////////
  111. UICommandTable Interface::command_table[] = {
  112.   {"AddBreakpoint",                    &Interface::AddBreakpoint},
  113.   {"AttachDevice",                     &Interface::AttachDevice},
  114.   {"ClearStatistics",                  &Interface::ClearStatistics},
  115.   {"DetachDevice",                     &Interface::DetachDevice},
  116.   {"DeleteBreakpoint",                 &Interface::DeleteBreakpoint},
  117.   {"ListAttachedDevices",              &Interface::ListAttachedDevices},
  118.   {"ListBreakpoints",                  &Interface::ListBreakpoints},
  119.   {"ListDevices",                      &Interface::ListDevices},
  120.   {"ListDeviceScript",                 &Interface::ListDeviceScript},
  121.   {"ListExecutionTraceRecord",         &Interface::ListExecutionTraceRecord},
  122.   {"ListDefaultExecutionTraceEntries", &Interface::ListDefaultExecutionTraceEntries},
  123.   {"ListGranularity",                  &Interface::ListGranularity},
  124.   {"ListMemory",                       &Interface::ListMemory},
  125.   {"ListMaximumAddress",               &Interface::ListMaximumAddress},
  126.   {"ListNumberOfAddressSpaces",        &Interface::ListNumberOfAddressSpaces},
  127.   {"ListPCRegisterName",               &Interface::ListPCRegisterName},
  128.   {"ListRegisters",                    &Interface::ListRegisters},
  129.   {"ListRegisterValue",                &Interface::ListRegisterValue},
  130.   {"ListRegisterDescription",          &Interface::ListRegisterDescription},
  131.   {"ListStatistics",                   &Interface::ListStatistics},
  132.   {"LoadProgram",                      &Interface::LoadProgram},
  133.   {"Reset",                            &Interface::Reset},
  134.   {"Run",                              &Interface::Run},
  135.   {"SetMemory",                        &Interface::SetMemory},
  136.   {"SetRegister",                      &Interface::SetRegister},
  137.   {"Step",                             &Interface::Step}
  138. };
  139.  
  140. ///////////////////////////////////////////////////////////////////////////////
  141. // Global flag to indicate an interrupt signal occurance
  142. ///////////////////////////////////////////////////////////////////////////////
  143. int Interface::interrupt_signal_flag=0;
  144.  
  145. ///////////////////////////////////////////////////////////////////////////////
  146. // Interrupt signal handler
  147. ///////////////////////////////////////////////////////////////////////////////
  148. void Interface::InterruptSignalHandler(int arg)
  149. {
  150.   Interface::interrupt_signal_flag=1;
  151. }
  152.  
  153. ///////////////////////////////////////////////////////////////////////////////
  154. // The constructor for UICommand objects
  155. ///////////////////////////////////////////////////////////////////////////////
  156. Interface::Interface(BasicCPU* c, BasicDeviceRegistry* r, BasicLoader* l) 
  157.     : number_of_commands(sizeof(command_table) / sizeof(UICommandTable)),
  158.       cpu((BasicCPU* const)c),
  159.       device_registry((BasicDeviceRegistry* const)r),
  160.       loader((BasicLoader* const)l)
  161. {
  162.   // Setup the Interrupt signal handler
  163.   struct sigaction newsig,oldsig;
  164.  
  165.   sigaction(SIGINT, (void*)0, &newsig);
  166. #ifdef __linux__
  167.   newsig.sa_handler=&Interface::InterruptSignalHandler;
  168. #elif _HPUX_SOURCE
  169.   newsig.sa_handler=&Interface::InterruptSignalHandler;
  170. #else
  171.   newsig.sa_handler=(void(*)(void))&Interface::InterruptSignalHandler;
  172. #endif
  173.   newsig.sa_flags=0;
  174.   sigaction(SIGINT, &newsig, &oldsig);
  175. }
  176.  
  177. ///////////////////////////////////////////////////////////////////////////////
  178. // Print the name of the Program Counter register
  179. ///////////////////////////////////////////////////////////////////////////////
  180. void Interface::ListPCRegisterName(char*)
  181. {
  182.   Put(cpu->NameOfProgramCounter());
  183. }
  184.  
  185. ///////////////////////////////////////////////////////////////////////////////
  186. // List the processor's execution trace record
  187. ///////////////////////////////////////////////////////////////////////////////
  188. void Interface::ListExecutionTraceRecord(char *)
  189. {
  190.   Put(cpu->ExecutionTraceRecord());  
  191. }
  192.  
  193. ///////////////////////////////////////////////////////////////////////////////
  194. // List the processor's default execution trace entries to display
  195. ///////////////////////////////////////////////////////////////////////////////
  196. void Interface::ListDefaultExecutionTraceEntries(char *)
  197. {
  198.   Put(cpu->DefaultExecutionTraceEntries());  
  199. }
  200.  
  201. ///////////////////////////////////////////////////////////////////////////////
  202. // Clear the cpu's statistics
  203. ///////////////////////////////////////////////////////////////////////////////
  204. void Interface::ClearStatistics(char *)
  205. {
  206.   cpu->ClearStatistics();
  207. }
  208.  
  209. ///////////////////////////////////////////////////////////////////////////////
  210. // List the cpu's statistics
  211. ///////////////////////////////////////////////////////////////////////////////
  212. void Interface::ListStatistics(char *)
  213. {
  214.   StatisticalInformationList list(cpu);
  215.  
  216.   for(int t=0;t<list.NumberOfElements();++t)
  217.   {
  218.     StatisticInformation info;
  219.     list.Element(t,info);
  220.     Put(info.Statistic());
  221.   }
  222. }
  223.  
  224. ///////////////////////////////////////////////////////////////////////////////
  225. // List the cpu's registers
  226. ///////////////////////////////////////////////////////////////////////////////
  227. void Interface::ListRegisters(char *)
  228. {
  229.   int t, max_width;
  230.   RegisterInformationList list(cpu);
  231.  
  232.   // Find the widest register name
  233.   for(max_width=0,t=0;t<list.NumberOfElements();++t)
  234.   {
  235.     RegisterInformation info;
  236.     list.Element(t,info);
  237.  
  238.     int l=strlen(info.Name());
  239.     if(max_width < l)
  240.       max_width=l;
  241.   }
  242.  
  243.   // send the register list to the user interface
  244.   for(t=0;t<list.NumberOfElements();++t)
  245.   {
  246.     RegisterInformation info;
  247.     list.Element(t,info);
  248.  
  249.     char *string=new char[max_width+strlen(info.HexValue())+3+1];
  250.  
  251.     strcpy(string,info.Name());
  252.     for(int s=strlen(string);s<max_width;++s)
  253.       string[s]=' ';
  254.     string[max_width]='\0';
  255.     strcat(string," = ");
  256.     strcat(string,info.HexValue());
  257.  
  258.     Put(string);
  259.   }
  260. }
  261.  
  262. ///////////////////////////////////////////////////////////////////////////////
  263. // List a register's  description
  264. ///////////////////////////////////////////////////////////////////////////////
  265. void Interface::ListRegisterDescription(char *arg)
  266. {
  267.   RegisterInformationList list(cpu);
  268.   char name[256];
  269.   int t;
  270.  
  271.   sscanf(arg,"%s",name);  
  272.  
  273.   for(t=0;t<list.NumberOfElements();++t)
  274.   {
  275.     RegisterInformation info;
  276.  
  277.     list.Element(t,info);
  278.     if(strcmp(name,info.Name())==0)
  279.     {
  280.       Put(info.Description());
  281.       return;
  282.     }
  283.   }
  284.   Put("ERROR: Invalid register name!");
  285. }
  286.  
  287.  
  288. ///////////////////////////////////////////////////////////////////////////////
  289. // Set one of the cpu's registers to the given value
  290. ///////////////////////////////////////////////////////////////////////////////
  291. void Interface::SetRegister(char *arg)
  292. {
  293.   RegisterInformationList list(cpu);
  294.   char name[256];
  295.   char value[256];
  296.   int t;
  297.  
  298.   if(sscanf(arg,"%s %s",name,value)!=2)
  299.   {
  300.     Put("ERROR: Invalid arguments!");
  301.   }
  302.   else
  303.   {
  304.     for(t=0;t<list.NumberOfElements();++t)
  305.     {
  306.       RegisterInformation info;
  307.  
  308.       list.Element(t,info);
  309.       if(strcmp(name,info.Name())==0)
  310.       {
  311.         cpu->SetRegister(name,value);
  312.         return;
  313.       }
  314.     }
  315.     Put("ERROR: Invalid register name!");
  316.   }
  317. }
  318.  
  319. ///////////////////////////////////////////////////////////////////////////////
  320. // List the value of one of the cpu's registers to the given value
  321. ///////////////////////////////////////////////////////////////////////////////
  322. void Interface::ListRegisterValue(char *arg)
  323. {
  324.   RegisterInformationList list(cpu);
  325.   char name[256];
  326.   int t;
  327.  
  328.   if(sscanf(arg,"%s",name)!=1)
  329.   {
  330.     Put("ERROR: Invalid arguments!");
  331.   }
  332.   else
  333.   {
  334.     for(t=0;t<list.NumberOfElements();++t)
  335.     {
  336.       RegisterInformation info;
  337.  
  338.       list.Element(t,info);
  339.       if(strcmp(name,info.Name())==0)
  340.       {
  341.         Put(info.HexValue());
  342.         return;
  343.       }
  344.     }
  345.     Put("ERROR: Invalid register name!");
  346.   }
  347. }
  348.  
  349.  
  350. ///////////////////////////////////////////////////////////////////////////////
  351. // Detach a device from the simulator
  352. ///////////////////////////////////////////////////////////////////////////////
  353. void Interface::DetachDevice(char *arg)
  354. {
  355.   unsigned int addr_space; 
  356.   unsigned int device_index; 
  357.  
  358.   if(sscanf(arg,"%d %d",&addr_space,&device_index)!=2)
  359.   {
  360.     Put("ERROR: Invalid arguments!");
  361.   }
  362.   else
  363.   {
  364.     if(addr_space>=cpu->NumberOfAddressSpaces())
  365.     {
  366.       Put("ERROR: Invalid address space!");
  367.       return;
  368.     }
  369.  
  370.     if(cpu->address_space[addr_space].DetachDevice(device_index)==0)
  371.     {
  372.       Put("ERROR: Couldn't detach device!");
  373.     }
  374.   }
  375. }
  376.  
  377. ///////////////////////////////////////////////////////////////////////////////
  378. // Attach a device to the simulator
  379. ///////////////////////////////////////////////////////////////////////////////
  380. void Interface::AttachDevice(char *arg)
  381. {
  382.   unsigned int addr_space; 
  383.   char name[256];
  384.   String device_args;
  385.  
  386.   String args(arg);
  387.   device_args=args.after('{');
  388.   device_args=device_args.before('}');
  389.   if(sscanf(arg,"%d %s", &addr_space, name)!=2)
  390.   {
  391.     Put("ERROR: Invalid arguments!");
  392.   }
  393.   else
  394.   {
  395.     if(addr_space >= cpu->NumberOfAddressSpaces())
  396.     {
  397.       Put("ERROR: Invalid address space!");
  398.       return;
  399.     }
  400.     
  401.     BasicDevice *device;
  402.     String deviceName(name);
  403.     if(device_registry->Create(deviceName, device_args, cpu, device))
  404.     {
  405.       cpu->address_space[addr_space].AttachDevice(device);
  406.     }
  407.     else
  408.     {
  409.       Put("ERROR: Couldn't create the device!");
  410.     }
  411.   }
  412. }
  413.  
  414. ///////////////////////////////////////////////////////////////////////////////
  415. // Add a breakpoint
  416. ///////////////////////////////////////////////////////////////////////////////
  417. void Interface::AddBreakpoint(char *arg)
  418. {
  419.   unsigned long address; 
  420.  
  421.   if(sscanf(arg,"%lx",&address)!=1)
  422.   {
  423.     Put("ERROR: Invalid arguments!");
  424.   }
  425.   else
  426.   {
  427.     breakpoint_list.Add(address);
  428.   }
  429. }
  430.  
  431. ///////////////////////////////////////////////////////////////////////////////
  432. // Delete a breakpoint
  433. ///////////////////////////////////////////////////////////////////////////////
  434. void Interface::DeleteBreakpoint(char *arg)
  435. {
  436.   unsigned long address; 
  437.  
  438.   if(sscanf(arg,"%lx",&address)!=1)
  439.   {
  440.     Put("ERROR: Invalid arguments!");
  441.   }
  442.   else
  443.   {
  444.     if(!breakpoint_list.Delete(address))
  445.       Put("ERROR: Couldn't delete breakpoint!");
  446.   }
  447. }
  448.  
  449. ///////////////////////////////////////////////////////////////////////////////
  450. // List the breakpoints
  451. ///////////////////////////////////////////////////////////////////////////////
  452. void Interface::ListBreakpoints(char *arg)
  453. {
  454.   String breakpoint;
  455.   unsigned long address;
  456.  
  457.   for(int t=0;t<breakpoint_list.NumberOfBreakpoints();++t)
  458.   {
  459.     breakpoint_list.GetBreakpoint(t,address);
  460.     breakpoint=IntToString(address,8);
  461.     Put(breakpoint);
  462.   }
  463. }
  464.  
  465. ///////////////////////////////////////////////////////////////////////////////
  466. // List the devices attached to the simulator
  467. ///////////////////////////////////////////////////////////////////////////////
  468. void Interface::ListAttachedDevices(char *arg)
  469. {
  470.   unsigned int addr_space;
  471.  
  472.   if(sscanf(arg,"%d",&addr_space)!=1)
  473.   {
  474.     Put("ERROR: Invalid arguments!");
  475.   }
  476.   else
  477.   {
  478.     if(addr_space>=cpu->NumberOfAddressSpaces())
  479.     {
  480.       Put("ERROR: Invalid address space!");
  481.       return;
  482.     }
  483.  
  484.     for(int t=0;t<cpu->address_space[addr_space].NumberOfAttachedDevices();++t)
  485.     {
  486.       String s;
  487.  
  488.       AddressSpaceDeviceInformation info;
  489.       cpu->address_space[addr_space].GetDeviceInformation(t,info);
  490.  
  491.       s=info.name;
  492.       s+=" {";
  493.       s+=info.initialization_arguments;
  494.       s+="}";
  495.       Put(s);
  496.     }
  497.   }
  498. }
  499.  
  500. ///////////////////////////////////////////////////////////////////////////////
  501. // List the devices in the simulator
  502. ///////////////////////////////////////////////////////////////////////////////
  503. void Interface::ListDevices(char *)
  504. {
  505.   int t;
  506.   
  507.   for(t=0;t<device_registry->NumberOfDevices();++t)
  508.   {
  509.     DeviceInformation info;
  510.     device_registry->Information(t,info);
  511.  
  512.     char *string = new char[strlen(info.name)+strlen(info.description)+4+1];
  513.     strcpy(string,info.name);
  514.  
  515.     Put(string);
  516.     delete[] string;
  517.   }
  518. }
  519.  
  520. ///////////////////////////////////////////////////////////////////////////////
  521. // List the UI script for the named device
  522. ///////////////////////////////////////////////////////////////////////////////
  523. void Interface::ListDeviceScript(char *arg)
  524. {
  525.   char name[256];
  526.  
  527.   if (sscanf(arg,"%s",name)!=1)
  528.   {
  529.     Put("ERROR: Invalid arguments!");
  530.   }
  531.   else
  532.   {
  533.     for(int t=0;t<device_registry->NumberOfDevices();++t)
  534.     {
  535.       DeviceInformation info;
  536.       device_registry->Information(t,info);
  537.  
  538.       if(strcmp(info.name,name)==0)
  539.       {
  540.         Put(info.script);
  541.         return;
  542.       }
  543.     }
  544.     Put("ERROR: Invalid device name!");
  545.   }
  546. }
  547.  
  548. ///////////////////////////////////////////////////////////////////////////////
  549. // List a memory block
  550. ///////////////////////////////////////////////////////////////////////////////
  551. void Interface::ListMemory(char* arg)
  552. {
  553.   unsigned int addr_space;
  554.   unsigned long address;
  555.   unsigned int length;
  556.   unsigned int wordsPerLine;
  557.   String line;
  558.  
  559.   if(sscanf(arg,"%x %x %x %x",&addr_space,&address,&length,&wordsPerLine) != 4)
  560.   {
  561.     Put("ERROR: Invalid arguments!");
  562.   }
  563.   else
  564.   {
  565.     if(addr_space >= cpu->NumberOfAddressSpaces())
  566.     {
  567.       Put("ERROR: Invalid address space!");
  568.       return;
  569.     }
  570.  
  571.     line = "";
  572.     int numberOfWords = 0;
  573.     for(int t = 0; t < length; ++t)
  574.     {
  575.       for(int s=0; s < cpu->Granularity(); ++s)
  576.       {
  577.         unsigned char value;
  578.         if(cpu->address_space[addr_space].Peek((address+t)*cpu->Granularity()+s,
  579.                                                value))
  580.         {
  581.           line += IntToString(value,2);
  582.         }
  583.         else
  584.         {
  585.           line += "xx";
  586.         }
  587.       }
  588.       ++numberOfWords;
  589.       if(numberOfWords >= wordsPerLine)
  590.       {
  591.         Put(line);
  592.         numberOfWords = 0;
  593.         line = "";
  594.       }
  595.       else
  596.       { 
  597.         line += " ";
  598.       }
  599.     } 
  600.     if(line != "")
  601.       Put(line);
  602.   }
  603. }
  604.  
  605. ///////////////////////////////////////////////////////////////////////////////
  606. // Perform a Step of instructions
  607. ///////////////////////////////////////////////////////////////////////////////
  608. void Interface::Step(char* arg)
  609. {
  610.   int number_of_steps;
  611.  
  612.   if(sscanf(arg,"%x", &number_of_steps)!=1)
  613.   {
  614.     Put("ERROR: Invalid arguments!");
  615.   }
  616.   else
  617.   {
  618.     for(int t=0;t<number_of_steps;++t)
  619.     {
  620.       String trace_record;
  621.       const char* message;
  622.       
  623.       trace_record="";
  624.       if((message=cpu->ExecuteInstruction(trace_record,1)) != (void*)0)
  625.       {
  626.         String reason("{SimulatorMessage {");
  627.         reason+=message;
  628.         reason+="}}";
  629.         Put(reason);
  630.         break;
  631.       }
  632.       Put(trace_record);
  633.     }
  634.   }
  635. }
  636.  
  637. ///////////////////////////////////////////////////////////////////////////////
  638. // Preform the Reset command 
  639. ///////////////////////////////////////////////////////////////////////////////
  640. void Interface::Reset(char* arg)
  641. {
  642.   // Reset the CPU (which should also reset the devices)
  643.   cpu->Reset();
  644. }
  645.  
  646. ///////////////////////////////////////////////////////////////////////////////
  647. // Perform the Run command 
  648. ///////////////////////////////////////////////////////////////////////////////
  649. void Interface::Run(char* arg)
  650. {
  651.   String trace_record;
  652.  
  653.   // Clear the interrupt flag (Set by SIGINT)
  654.   interrupt_signal_flag=0;
  655.  
  656.   // Run until something stops us!!!
  657.   while(1)
  658.   {
  659.     const char *message;
  660.  
  661.     if((message=cpu->ExecuteInstruction(trace_record,0)) != (char*)0)
  662.     {
  663.       String reason("Execution stopped: ");
  664.       reason+=message;
  665.       Put(reason);
  666.       break;
  667.     }
  668.     else if(breakpoint_list.Check(cpu->ValueOfProgramCounter()))
  669.     {
  670.       Put("Execution stopped at a breakpoint!");
  671.       break;
  672.     }
  673.     else if(interrupt_signal_flag)
  674.     {
  675.       Put("Execution interrupted!");
  676.       break;
  677.     }
  678.   }
  679. }
  680.  
  681. ///////////////////////////////////////////////////////////////////////////////
  682. // List the Maximum Address allow by the give address space
  683. ///////////////////////////////////////////////////////////////////////////////
  684. void Interface::ListMaximumAddress(char* arg)
  685. {
  686.   unsigned int addr_space;
  687.   unsigned long max;
  688.   char buffer[40];
  689.  
  690.   if(sscanf(arg,"%x", &addr_space)!=1)
  691.   {
  692.     Put("ERROR: Invalid arguments!");
  693.   }
  694.   else
  695.   {
  696.     if(addr_space>=cpu->NumberOfAddressSpaces())
  697.     {
  698.       Put("ERROR: Invalid address space!");
  699.       return;
  700.     }
  701.  
  702.     max=cpu->address_space[addr_space].MaximumAddress();
  703.  
  704.     sprintf(buffer,"%x",max);
  705.     Put(buffer);
  706.   }
  707. }
  708.  
  709. ///////////////////////////////////////////////////////////////////////////////
  710. // List the number of address spaces for the cpu
  711. ///////////////////////////////////////////////////////////////////////////////
  712. void Interface::ListNumberOfAddressSpaces(char*)
  713. {
  714.   char buffer[80];
  715.  
  716.   sprintf(buffer,"%d",cpu->NumberOfAddressSpaces());
  717.   Put(buffer);
  718. }
  719.  
  720. ///////////////////////////////////////////////////////////////////////////////
  721. // List the granularity of the cpu
  722. ///////////////////////////////////////////////////////////////////////////////
  723. void Interface::ListGranularity(char*)
  724. {
  725.   char buffer[80];
  726.  
  727.   sprintf(buffer,"%d",cpu->Granularity());
  728.   Put(buffer);
  729. }
  730.  
  731.  
  732. ///////////////////////////////////////////////////////////////////////////////
  733. // Set a memory location to the given value
  734. ///////////////////////////////////////////////////////////////////////////////
  735. void Interface::SetMemory(char *arg)
  736. {
  737.   unsigned int addr_space;
  738.   unsigned long address;
  739.   char value[256];
  740.  
  741.   if(sscanf(arg,"%d %x %s",&addr_space,&address,value)!=3)
  742.   {
  743.     Put("ERROR: Invalid arguments!");
  744.   }
  745.   else
  746.   {
  747.     if(addr_space>=cpu->NumberOfAddressSpaces())
  748.     {
  749.       Put("ERROR: Invalid address space!");
  750.       return;
  751.     }
  752.     if (address > cpu->address_space[addr_space].MaximumAddress())
  753.     {
  754.       Put("ERROR: Invalid address!");
  755.       return;
  756.     }
  757.  
  758.     address *= cpu->Granularity();
  759.     for(int t=0;t<cpu->Granularity();++t)
  760.     {
  761.       String val(value);
  762.       cpu->address_space[addr_space].Poke(address+t,StringToInt(val(t*2,2)));
  763.     }
  764.   }
  765. }
  766.  
  767.  
  768. ///////////////////////////////////////////////////////////////////////////////
  769. // Load the named program into the address space
  770. ///////////////////////////////////////////////////////////////////////////////
  771. void Interface::LoadProgram(char *arg)
  772. {
  773.   unsigned int addr_space;
  774.   char name[256];
  775.   String error;
  776.  
  777.   if(sscanf(arg,"%d %s",&addr_space,name)!=2)
  778.   {
  779.     Put("ERROR: Invalid arguments!");
  780.   }
  781.   else
  782.   {
  783.    error=loader->Load(name,addr_space);
  784.  
  785.    Put(error);
  786.   }
  787. }
  788.